﻿using System;
using System.Diagnostics;
using System.IO;
using System.Windows.Forms;
using Moonlite.Platform.General;
using Moonlite.Platform.Project;
using Moonlite.ExtensionApi;
using Moonlite.ExtensionApi.GlobalInterfaces;

namespace Moonlite.Compiling
{
    public class GameManager : IGameManager
    {
        private static GameManager instance;
        public static GameManager Instance
        {
            get { return instance; }
        }

        public event EventHandler GameProcessExit;
        internal Process GameProcess { get; set; }
        private void OnGameProcessExit(EventArgs e)
        {
            EventHandler handler = GameProcessExit;
            if (handler != null)
            {
                handler(null, e);
            }
        }

        private void OnGameProcessExited(object sender, EventArgs e)
        {
            OnGameProcessExit(e);
        }

        public bool StartGame(IProject project, bool compile)
        {
            if (project.Type == ProjectType.Jass)
            {
                if (compile == true)
                {
                    if (CompilerManager.ExecuteWc3() == false)
                    {
                        return false;
                    }
                }

                string normalPath = String.Format("{0}\\{1}", Global.Warcraft3RegistryPath, Global.Warcraft3RegistryKeyName);
                if (RegistrySettings.ExistsFromCurrentUserKey(normalPath) == false)
                {
                    ShowError(String.Format("Moonlite Map Studio can't find the Warcraft 3 executable. Please check your Warcraft 3 installation, or check whether the following registry key exists: {0}{1}{0}To view registry keys, enter the Start menu, open the Run tool and type \"regedit\", then navigate to the given registry key.{0}{0}If the problem persists even though you have installed Warcraft 3, please report the issue with the Bug Reporter. (View > Run Bug Reporter)", Environment.NewLine, normalPath));
                    return false;
                }

                string expansionPath = String.Format("{0}\\{1}", Global.Warcraft3RegistryPath, Global.Warcraft3XRegistryKeyName);
                string executablePath = RegistrySettings.ExistsFromCurrentUserKey(expansionPath) == true ?
                    (string)RegistrySettings.ReadFromCurrentUserKey(expansionPath) :
                    (string)RegistrySettings.ReadFromCurrentUserKey(normalPath);
                if (Path.GetFileName(executablePath) != "war3.exe")
                {
                    executablePath = Path.GetDirectoryName(executablePath) + "\\war3.exe";
                }

                string mapPath = project.GetMapPath();
                string newMapPath = String.Format("{0}\\Maps\\Moonlite Map Studio\\{1}", Path.GetDirectoryName(executablePath), Path.GetFileName(mapPath));
                if (File.Exists(newMapPath) == true)
                {
                    File.Delete(newMapPath);
                }

                DirectoryHelper.CreatePath(newMapPath);
                File.Copy(mapPath, newMapPath);
                ProcessStartInfo info = new ProcessStartInfo(executablePath, String.Format("-window -loadfile \"Maps\\Moonlite Map Studio\\{0}\"", Path.GetFileName(mapPath))) { UseShellExecute = false };
                GameProcess = new Process();
                GameProcess.StartInfo = info;
                GameProcess.Exited += OnGameProcessExited;
                GameProcess.Start();
            }
            else
            {
                if (compile == true)
                {
                    if (CompilerManager.ExecuteAndromeda(project, true, true, true, false, "") == false)
                    {
                        return false;
                    }
                }

                string normalPath = String.Format("{0}\\{1}", Global.Starcraft2RegistryPath, Global.Starcraft2RegistryKeyName);
                if (RegistrySettings.ExistsFromLocalMachineKey(normalPath) == false)
                {
                    ShowError(String.Format("Moonlite Map Studio can't find the Starcraft 2 executable. Please check your Starcraft 2 installation, or check whether the following registry key exists: {0}{1}{0}To view registry keys, enter the Start menu, open the Run tool and type \"regedit\", then navigate to the given registry key.{0}{0}If the problem persists even though you have installed Starcraft 2, please report the issue with the Bug Reporter. (View > Run Bug Reporter)", Environment.NewLine, normalPath));
                    return false;
                }

                string expansionPath = String.Format("{0}\\{1}", Global.Starcraft2RegistryPath, Global.Starcraft2XRegistryKeyName);
                string executablePath = RegistrySettings.ExistsFromLocalMachineKey(expansionPath) == true ?
                    (string)RegistrySettings.ReadFromLocalMachineKey(expansionPath) :
                    (string)RegistrySettings.ReadFromLocalMachineKey(normalPath);
                if (Path.GetFileName(executablePath) != "StarCraft II.exe")
                {
                    executablePath = Path.GetDirectoryName(executablePath) + "\\StarCraft II.exe";
                }

                string mapPath = project.GetMapPath();
                DirectoryHelper.CreatePath(mapPath);
                ProcessStartInfo info = new ProcessStartInfo(executablePath, "-run \"" + mapPath + "\"") { UseShellExecute = false };
                GameProcess = new Process();
                GameProcess.StartInfo = info;
                GameProcess.Exited += OnGameProcessExited;
                GameProcess.Start();
            }

            return true;
        }

        public void StopGame()
        {
            if (GameProcess != null && GameProcess.HasExited == false)
            {
                GameProcess.Kill();
            }
        }

        private static void ShowError(string message)
        {
            MessageBox.Show(message, "Moonlite Map Studio", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
        }

        private GameManager()
        {
            try { Global.Instance.RegisterService(this, GetType().GetInterface("IGameManager")); }
            catch { }
        }

        static GameManager()
        {
            instance = new GameManager();
        }
    }
}
